package com.wyclabs.gateway.auth;


import com.alibaba.fastjson.JSONObject;
import com.wyclabs.commons.constants.ErrorCodes;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 处理zuul在调用其他服务时，其他服务繁忙、或者用户未登录的情况
 * @author rs
 * @date 2019/10/29
 */
@Component
public class CustomizeAuthenticationEntryPoint extends HttpBasicServerAuthenticationEntryPoint {

    private static final String BUSY_SIGN = "busy";

    private String headerValue = createHeaderValue("Realm");

    private static String createHeaderValue(String realm) {
        String WWW_AUTHENTICATE_FORMAT = "Basic realm=\"%s\"";
        return String.format(WWW_AUTHENTICATE_FORMAT, realm);
    }

    @Override
    public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException authException) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().add("Content-Type", "application/json; charset=UTF-8");
        response.getHeaders().set(HttpHeaders.AUTHORIZATION, headerValue);
        JSONObject result = new JSONObject();

        if (authException.getMessage().contains(BUSY_SIGN)) {
            result.put("status", ErrorCodes.ERROR_SERVER_BUSY.getCode());
            result.put("message", ErrorCodes.ERROR_SERVER_BUSY.getDescription());
        } else {
            result.put("status", ErrorCodes.ERROR_NOT_LOGIN.getCode());
            result.put("message", ErrorCodes.ERROR_NOT_LOGIN.getDescription());
        }

        byte[] dataBytes = result.toString().getBytes();
        DataBuffer bodyDataBuffer = response.bufferFactory().wrap(dataBytes);
        return response.writeWith(Mono.just(bodyDataBuffer));
    }

    @Override
    public void setRealm(String realm) {
        headerValue = createHeaderValue(realm);
    }
}
